package tasoloikka;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.ArrayList;

public class Game {

  //Luokat
  private ActionListener actionListener;
  private Player player;
  private Map map;
  private Gun gun;
  //Muuttujat
  private int screenWidth;
  private int screenHeight;
  private int mapWidth = 64;
  private int mapHeight = 40;
  private String mapName = "map01";
  private ArrayList<Bullet> bullets = new ArrayList<Bullet>();

  //Game luokan konstruktori
  public Game(ActionListener actionListener, int screenWidth, int screenHeight) {
    //Tuodana muuttujia
    this.screenHeight = screenHeight;
    this.screenWidth = screenWidth;
    //Tuodaan luokkia
    this.actionListener = actionListener;
    //Luodaan luokat
    this.gun = new Gun(screenWidth,screenHeight);
    this.player = new Player(gun);
    this.map = new Map(mapWidth, mapHeight, mapName, actionListener);
  }

  //Näppäinkomentojen tarkistus
  public void keyInput() {
    gun.calculateAim(actionListener.mouseX, actionListener.mouseY);

    if (actionListener.arrowLeft) {
      player.setPositionX(-4);
      collisionDetection();
    }

    if (actionListener.arrowRight) {
      player.setPositionX(4);
      collisionDetection();
    }

//    if (actionListener.arrowUp) {
//      player.setPositionY(-20);
//      collisionDetection();
//    }

    if (actionListener.shift) {
      map.saveMap();
    }

    //Jos karttaeditori on päällä, nämä nappulat toimivat
    if (map.getMapEditorEnabled()) {


      if (actionListener.mouseClicked) {
        actionListener.mouseClicked = false;
        map.changeBlock();
      }
    } else {
      if (actionListener.mouseClicked) {
        actionListener.mouseClicked = false;
        bullets.add(new Bullet(player.getPositionX() + (player.getWidth() / 2), player.getPositionY() + (player.getHeight() / 2), actionListener.mouseX, actionListener.mouseY, 3, 3));
      }
    }
  }

  //Päivitetään kaikki tiedot mitä pelissä tulee muuttumaan
  public void update() {
    keyInput();
    Gravity();

    //Lasketaan luodit
    if (bullets.size() > 0) {
      calculateBullets();
    }
    
    //Siirretään ase oikeaan kohtaan
    gun.setPositionX(player.getPositionX());
    gun.setPositionY(player.getPositionY());
  }

  //Päivitetään ammukset
  public void calculateBullets() {
    for (int i = 0; i < bullets.size(); i++) {
      bullets.get(i).moveBullet();
      bulletCollisionDetection(i);

    }
  }

  //Luotien törmäystarkistus
  public void bulletCollisionDetection(int x) {
    Rectangle rectBlock;
    Rectangle bulletRectangle = bullets.get(x).getRectangle();
    Tile[][] loadingMap = map.getMap();

    for (int i = 0; i < mapWidth; i++) {
      for (int j = 0; j < mapHeight; j++) {
        if (loadingMap[i][j] != null) {
          if (loadingMap[i][j].getBlock()) {

            rectBlock = loadingMap[i][j].getRectangle();
            if (bulletRectangle.intersects(rectBlock)) {
              bullets.remove(x);
              return;
            }
          }
        }
      }
    }
  }

  //Piirtopöytä
  public void paint(Graphics gbi) {
    //Pyyhitään ruudun tausta
    gbi.setColor(Color.black);
    gbi.fillRect(0, 0, screenWidth, screenHeight);

    //Piirretään muita luokkia
    map.paint(gbi);
    player.paint(gbi);
    gun.paint(gbi);

    //Tähän kohtaan tulee pelaajan eteen tulevat koristeet

    //Debuggausta
    gbi.setColor(Color.white);
    gbi.drawString("Mouse(" + actionListener.mouseX + "," + actionListener.mouseY + ") /16(" + actionListener.mouseX / 16 + "," + actionListener.mouseY / 16 + ")", 10, 40);

    //Piirretään luodit
    if (bullets.size() > 0) {
      for (int i = 0; i < bullets.size(); i++) {
        bullets.get(i).paint(gbi);
      }
    }
  }

  //Lasketaan pelaajan törmäystarkistus
  public void collisionDetection() {
    Tile[][] loadingMap = map.getMap();

    Rectangle rectPlayer = player.getRectangle();
    Rectangle rectBlock;

    //Tehdään pelaajan reunoista helposti tarkasteltavia muuttujia
    int playerBottom = player.getPositionY() + player.getHeight();
    int playerTop = player.getPositionY();
    int playerRight = player.getPositionX() + player.getWidth();
    int playerLeft = player.getPositionX();
    int playerPrevBottom = player.getPrevPositionY() + player.getHeight();
    int playerPrevTop = player.getPrevPositionY();
    int playerPrevRight = player.getPrevPositionX() + player.getWidth();
    int playerPrevLeft = player.getPrevPositionX();

    for (int i = 0; i < mapWidth; i++) {
      for (int j = 0; j < mapHeight; j++) {
        if (loadingMap[i][j] != null) {
          if (loadingMap[i][j].getBlock()) {


            rectBlock = loadingMap[i][j].getRectangle();
            if (rectPlayer.intersects(rectBlock)) {

              //Tehdään laatikon reunoista helposti tarkasteltavia muuttujia
              int tileBottom = loadingMap[i][j].getPositionY() + loadingMap[i][j].getHeight();
              int tileTop = loadingMap[i][j].getPositionY();
              int tileRight = loadingMap[i][j].getPositionX() + loadingMap[i][j].getWidth();
              int tileLeft = loadingMap[i][j].getPositionX();


              //Jos pelaaja on pelikan päällä tai alla oikealla kohdalla
              if (playerRight > (tileLeft + player.getLastMovementX()) && playerLeft < (tileRight + player.getLastMovementX())) {
                //Kosketus ylhäältä
                if (playerBottom >= tileTop
                        && playerPrevBottom <= tileTop) {
                  player.setY(loadingMap[i][j].getPositionY() - player.getHeight());
                  player.setPrevPositionY();
                  player.setAllowJump(true);
                }

                //Kosketus alhaalta
                if (playerTop <= tileBottom
                        && playerPrevTop >= tileBottom) {
                  player.setY(loadingMap[i][j].getPositionY() + loadingMap[i][j].getHeight());
                  player.setPrevPositionY();
                  player.setJump(0);
                }

              }

              //Jos pelaaja on palikan sivuilla oikealla kohdalla
              if (playerTop < (tileBottom + player.getLastMovementY()) && playerBottom > (tileTop + player.getLastMovementY())) {
                //Kosketus oikealta
                if (playerLeft <= tileRight
                        && playerPrevLeft >= tileRight) {
                  player.setX(loadingMap[i][j].getPositionX() + loadingMap[i][j].getWidth());
                  player.setPrevPositionX();
                }

                //Kosketus vasemmalta
                if (playerRight >= tileLeft
                        && playerPrevRight <= tileLeft) {
                  player.setX(loadingMap[i][j].getPositionX() - player.getWidth());
                  player.setPrevPositionX();
                }


              }
            }
          }
        }
      }
    }
  }

  //Lasketaan painovoima
  public void Gravity() {
    if (actionListener.space && player.getAllowJump()) {
      player.startJump(10);
      player.setAllowJump(false);
      collisionDetection();
    } else if (player.getJump() > -9) {
      player.jumpInProgress();
      collisionDetection();
    } else {
      player.setPositionY(+10);
      player.setAllowJump(false);
      collisionDetection();
    }
  }

  //Map nappulat
  public void buttonK() {
    map.mapEditor();
  }

  public void leftButton() {
    map.nextBlock(false);
  }

  public void rightButton() {
    map.nextBlock(true);

  }
}
